home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / misc / FetchRefs1.3.lha / FetchRefs1.3 / Source.lha / Source / FetchRefs / Main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-04  |  13.5 KB  |  568 lines

  1. /* main.c
  2. Originaly written by Anders Melchiorsen, modified by Roland Florac
  3. SPrintf routine slightly modified (caused the CPU 040 060 to crash)
  4. Modified from the original version for the ARexx interface */
  5.  
  6. #include "FetchRefs.h"
  7. #include <libraries/locale.h>
  8. #include <clib/locale_protos.h>
  9. #include <pragmas/locale_pragmas.h>
  10.  
  11. static void __regargs LoadDataFragmented (BPTR file);
  12. static __regargs void ReadWBArgs (struct WBArg * wb_arg);
  13.  
  14. #define VERSION_CATALOGUE 1
  15.  
  16. const UBYTE Vers_Tag[] = "$VER: FetchRefs " VERSION DATE;
  17.  
  18. struct Library * IntuitionBase;
  19. struct Library * RexxSysBase, * LocaleBase;
  20. APTR catalogue;
  21.  
  22. /* ReadArgs stuff */
  23. UBYTE Template[] = "FILES/M,PORTNAME";
  24. UBYTE CLI_Help[] = "\n"
  25.     "FetchRefs [[FILES] <wildcard> [...]] [PORTNAME <name>]\n"
  26.     "\n"
  27.     "- FILES are index files generated by GenerateIndex\n"
  28.     "- Default ARexx port name is FETCHREFS\n"
  29.     "- Please read the guide for further information\n"
  30.     "\n";
  31.  
  32. struct RDArgs *Args;
  33. struct {
  34.     STRPTR  (*Files)[];
  35.     STRPTR  Portname;
  36. } StartupArgs;
  37.  
  38. /* Other variables */
  39. struct List FileList;
  40. APTR FilePool;
  41. long WorkBench = 0;    /* Signale que le programme a été démarré du WorkBench */
  42.  
  43. /* Localized strings */
  44. char * texts[] = {
  45.     "AutoDoc/include file look-up utility",
  46.     "You need triton.library V%ld+!", "Error opening ARexx port",
  47.     "There is a problem with this tool type:\n%s\n(%s [#%ld])",
  48.     "Warning: no match for pattern '%s'", "Removing FetchRefs...",
  49.     "FetchRefs " VERSION " by Anders Melchiorsen & Roland Florac", "Okay",
  50.     "Select reference",
  51.     "Search _pattern", "Fetch reference", "_List file", "Cancel",
  52.     "Could not open guide", "Could not open amigaguide.library v34+",
  53.     "FetchRefs: Reference not found", "FetchRefs: Aborted!"
  54. };
  55.  
  56. char * __regargs GetString (long indice)
  57. {   STRPTR def = texts[indice];
  58.     return (catalogue ? GetCatalogStr (catalogue, indice, def) : def);
  59. }
  60.  
  61. void ouverture_port_ARexx (void)
  62. {   Forbid ();
  63.     if (FindPort ("FETCHREFS") == 0)
  64.     rexxPort = CreatePort ("FETCHREFS", 0);
  65.     Permit ();
  66. }
  67.  
  68. static void fermeture_port_ARexx (void)
  69. {   if (rexxPort)
  70.     {    RemPort (rexxPort);
  71.     DeletePort (rexxPort);
  72.     CloseLibrary (RexxSysBase);
  73.     }
  74. }
  75.  
  76. main (LONG argc, STRPTR argv)
  77. {
  78.     STRPTR port;
  79.     struct WBStartup * argmsg;        struct WBArg * wb_arg;
  80.     struct MsgPort *otherport;
  81.  
  82.     if (LocaleBase = OpenLibrary ("locale.library", 38))
  83.     catalogue = OpenCatalog (NULL, "FetchRefs.catalog", OC_Version, VERSION_CATALOGUE, TAG_DONE);
  84.  
  85.     IntuitionBase = OldOpenLibrary ("intuition.library");
  86.     if (IntuitionBase == 0)
  87.     CloseAll (0);
  88.  
  89.     /* We need Triton */
  90.     if (! TR_OpenTriton (TRITON14VERSION,
  91.         TRCA_Name,        "FetchRefs",
  92.         TRCA_LongName,  "FetchRefs",
  93.         TRCA_Info,        GetString (TEXTE_RECHERCHE),
  94.         TRCA_Version,   VERSION,
  95.         TRCA_Release,   RELEASE,
  96.         TRCA_Date,        DATE,
  97.         TAG_END))
  98.     {
  99.     PostMessage (GetString(TEXTE_TRITON), TRITON14VERSION);
  100.     CloseAll (0);
  101.     }
  102.  
  103.     /* Initialize list */
  104.     NewList (&FileList);
  105.  
  106.     if (!(FilePool = LibCreatePool (MEMF_CLEAR, 8 * 1024, 8 * 1024)))
  107.     CloseAll (ERROR_NO_FREE_STORE);
  108.  
  109.     /* Allocate memory for argument parsing */
  110.     if (!(Args = AllocDosObject (DOS_RDARGS, NULL)))
  111.     CloseAll (ERROR_NO_FREE_STORE);
  112.  
  113.     /* Convert tool types to something that ReadArgs() understands if we are
  114.      * run by Workbench.
  115.      */
  116.     if (argc == 0)
  117.     {    argmsg = (struct WBStartup *) argv;
  118.     wb_arg = argmsg->sm_ArgList ;
  119.     WorkBench = 0;
  120.     ReadWBArgs (wb_arg);
  121.     }
  122.  
  123.     /* Activate extended help */
  124.     Args->RDA_ExtHelp = CLI_Help;
  125.  
  126.     /* Parse arguments from either the Shell or Workbench */
  127.     if (!(ReadArgs (Template, (LONG *)&StartupArgs, Args)))
  128.     CloseAll (IoErr());
  129.  
  130.     /* Do not bother to start if the user pressed CTRL-C during load
  131.      * time or during a 'FetchRefs ?' help session.
  132.      */
  133.     if (CheckSignal (SIGBREAKF_CTRL_C))
  134.     CloseAll (0);
  135.  
  136.     /* Try to allocate an ARexx port. Default port name is FETCHREFS.
  137.      * We quit both copies of FetchRefs if our port name is used.
  138.      */
  139.     port = StartupArgs.Portname;
  140.  
  141.     if (!port)
  142.     port = "FETCHREFS";
  143.  
  144.     if (otherport = FindPort (port))
  145.     {    Signal (otherport->mp_SigTask, SIGBREAKF_CTRL_C);
  146.  
  147.     CloseAll (ERROR_RUNTWICE);
  148.     }
  149.  
  150.     /* Open ARexx port */
  151.     ouverture_port_ARexx ();
  152.     if (! rexxPort)
  153.     {
  154.     PostMessage (GetString (TEXTE_AREXX_PORT));
  155.     CloseAll (0);
  156.     }
  157.  
  158.     /* Expand each wildcard (which can also be just a file) and read refs */
  159.     if (StartupArgs.Files)
  160.     ReadWild (StartupArgs.Files);
  161.  
  162.     /* Install Commodities Broker */
  163.     InstallCx (port);
  164.  
  165.     /* Activate ARexx handler and quit when it returns */
  166.     MessageLoop ();
  167.     CloseAll (0);
  168. }
  169.  
  170. /* ReadWBArgs() - convert tool types to ReadArgs() string */
  171. static __regargs void ReadWBArgs (struct WBArg * wb_arg)
  172. {
  173.     struct DiskObject *diskobj;
  174.     STRPTR ToolTypeArgs;
  175.  
  176.     if (!(ToolTypeArgs = AllocVec (1024, NULL)))
  177.     CloseAll (ERROR_NO_FREE_STORE);
  178.  
  179.     CurrentDir (wb_arg->wa_Lock);
  180.     if (diskobj = GetDiskObject (wb_arg->wa_Name))
  181.     {
  182.     int err;
  183.  
  184.     if (err = ToolTypesToReadArgs (diskobj->do_ToolTypes, Template, ToolTypeArgs, 1))
  185.     {
  186.         UBYTE errortxt[80];
  187.  
  188.         Fault (err & 0xFFFF, NULL, errortxt, 80);
  189.  
  190.         PostMessage(
  191.         GetString (TEXTE_TOOLTYPE),
  192.         diskobj->do_ToolTypes[err >> 16],
  193.         errortxt,
  194.         err & 0xFFFF);
  195.  
  196.         FreeDiskObject (diskobj);
  197.         CloseAll (0);
  198.     }
  199.  
  200.     Args->RDA_Source.CS_Buffer = ToolTypeArgs;
  201.     Args->RDA_Source.CS_Length = strlen(ToolTypeArgs);
  202.     Args->RDA_Flags = RDAF_NOPROMPT;
  203.  
  204.     FreeDiskObject (diskobj);
  205.     }
  206. }
  207.  
  208. /* ReadWild() - read all files that match argument
  209.  * The argument is a pointer to an NULL terminated array of STRPTR (as
  210.  * returned by ReadArgs("ARG/M"); ). */
  211. void __regargs ReadWild (STRPTR (*patharrayptr)[])
  212. {
  213.     struct AnchorPath *fanchor;
  214.     LONG cnt;
  215.     STRPTR path;
  216.  
  217.     if (!(fanchor = AllocVec (sizeof(struct AnchorPath), MEMF_CLEAR)))
  218.     return;
  219.  
  220.     for (cnt = 0; path = (*patharrayptr)[cnt]; cnt++)
  221.     {
  222.     if (MatchFirst (path, fanchor) == 0)
  223.     {
  224.         do
  225.         {
  226.         BPTR olddir;
  227.  
  228.         olddir = CurrentDir (fanchor->ap_Current->an_Lock);
  229.         ReadRefs (fanchor->ap_Info.fib_FileName, fanchor->ap_Info.fib_Size);
  230.         CurrentDir (olddir);
  231.         }
  232.         while (MatchNext(fanchor) == 0);
  233.     }
  234.     else
  235.         PostMessage (GetString (TEXTE_PATTERN), path);
  236.  
  237.     MatchEnd (fanchor);
  238.     }
  239.     FreeVec (fanchor);
  240. }
  241.  
  242. /* ReadRefs() - Read all references in 'filename' (with length 'filesize') */
  243. void __regargs ReadRefs (STRPTR filename, LONG filesize)
  244. {
  245.     BPTR file;
  246.  
  247.     /* First ensure that we can really open the file */
  248.     if (!(file = Open (filename, MODE_OLDFILE)))
  249.     return;
  250.  
  251.     /* If we cannot load the file fast then try the slower routine */
  252.     if (!LoadData (file, filesize))
  253.     LoadDataFragmented (file);
  254.  
  255.     Close (file);
  256. }
  257.  
  258. /* LoadData() - fast loader using large memory chunk */
  259. BOOL __regargs LoadData (BPTR file, LONG filesize)
  260. {
  261.     struct FileEntry *fileentry;
  262.     char *gotto, *buffer;
  263.  
  264.     if (!(buffer = LibAllocPooled (FilePool, filesize)))
  265.     return FALSE;
  266.  
  267.     Read (file, buffer, filesize);
  268.  
  269.     gotto = buffer;
  270.     buffer += filesize;
  271.  
  272.     while (gotto < buffer)
  273.     {
  274.     LONG size;
  275.  
  276.     /* The size is saved in the .ln_Succ field of the Node */
  277.     size = (LONG)(((struct Node *)gotto)->ln_Succ);
  278.  
  279.     if (((struct Node *) gotto)->ln_Type == 1)
  280.     {
  281.         fileentry = (struct FileEntry *) gotto;
  282.         AddTail (&FileList, &fileentry->node);
  283.         NewList (&fileentry->RefsList);
  284.         fileentry->node.ln_Name = fileentry->Name;
  285.     }
  286.     else if (((struct Node *)gotto)->ln_Type == 2)
  287.     {
  288.         struct RefsEntry *refsentry;
  289.         refsentry = (struct RefsEntry *) gotto;
  290.         AddTail (&fileentry->RefsList, &refsentry->node);
  291.         refsentry->node.ln_Name = fileentry->Name;
  292.     }
  293.     gotto += size;
  294.     }
  295.  
  296.     return TRUE;
  297. }
  298.  
  299. /* LoadDataFragmented() - Load into fragmented memory. A bit slower. */
  300. static void __regargs LoadDataFragmented (BPTR file)
  301. {
  302.     char *buffer;
  303.     struct FileEntry *fileentry;
  304.     struct Node tmpnode;
  305.  
  306.     while (Read (file, &tmpnode, sizeof(struct Node)))
  307.     {
  308.     /* The size of the node is saved in the .ln_Succ filed */
  309.     if (!(buffer = LibAllocPooled (FilePool, (LONG)tmpnode.ln_Succ)))
  310.         break;
  311.  
  312.     /* Fill in the node with information from the file */
  313.     // fread (buffer + sizeof(struct Node), (LONG)tmpnode.ln_Succ - sizeof(struct Node), 1, file);
  314.     Read (file, buffer + sizeof(struct Node), (LONG)tmpnode.ln_Succ - sizeof(struct Node));
  315.  
  316.     if (tmpnode.ln_Type == 1)
  317.     {
  318.         /* A new file starts here */
  319.         fileentry = ((struct FileEntry *)buffer);
  320.  
  321.         AddTail (&FileList, &fileentry->node);
  322.         NewList (&fileentry->RefsList);
  323.         fileentry->node.ln_Name = fileentry->Name;
  324.     }
  325.     else if (tmpnode.ln_Type == 2)
  326.     {
  327.         struct RefsEntry *refsentry = ((struct RefsEntry *)buffer);
  328.  
  329.         /* Another reference in the current file */
  330.         AddTail (&fileentry->RefsList, &refsentry->node);
  331.         refsentry->node.ln_Name = fileentry->Name;
  332.     }
  333.     }
  334. }
  335.  
  336. /* FreeRefs() - Release all files from memory and re-initialize list */
  337. void FreeRefs ()
  338. {
  339.     NewList (&FileList);
  340.     LibDeletePool (FilePool);
  341.  
  342.     if (!(FilePool = LibCreatePool (MEMF_CLEAR, 8 * 1024, 8 * 1024)))
  343.     CloseAll (ERROR_NO_FREE_STORE);
  344. }
  345.  
  346. struct TagItem TellWeStopOutline[] =
  347. {
  348.     WindowID (0xC0DEDBAD),
  349.     WindowPosition (TRWP_CENTERDISPLAY),
  350.     WindowTitle ("FetchRefs " VERSION),
  351.     WindowBackfillReq,
  352.     WindowFlags (TRWF_NOACTIVATE|TRWF_NOESCCLOSE|TRWF_NOSIZEGADGET|TRWF_NOZIPGADGET|TRWF_NOCLOSEGADGET),
  353.  
  354.     HorizGroupA,
  355.     Space,
  356.     VertGroupA,
  357.         Space,
  358.         GroupBox, ObjectBackfillB,
  359.         HorizGroupA,
  360.         Space,
  361.         VertGroupA,
  362.             Space,
  363.             TextN (0),
  364.             Space,
  365.         EndGroup,
  366.         Space,
  367.         EndGroup,
  368.         Space,
  369.     EndGroup,
  370.     Space,
  371.     EndGroup,
  372.  
  373. EndProject
  374. };
  375.  
  376. /****** triton.lib/TR_CloseTriton ******
  377. *   NAME
  378. *    TR_CloseTriton -- Closes Triton easily.
  379. *
  380. *   SYNOPSIS
  381. *    TR_CloseTriton()
  382. *
  383. *    VOID TR_CloseTriton(VOID);
  384. *
  385. *   FUNCTION
  386. *    Closes the application created by OpenTriton()
  387. *    and closes triton.library.
  388. *
  389. *   SEE ALSO
  390. *    TR_OpenTriton()
  391. ******/
  392.  
  393. REGS void TR_CloseTriton (void)
  394. {
  395.     if (__Triton_Support_App)
  396.     {
  397.     TR_DeleteApp (__Triton_Support_App);
  398.     __Triton_Support_App = NULL;
  399.     }
  400.  
  401.     if (TritonBase)
  402.     {
  403.     CloseLibrary (TritonBase);
  404.     TritonBase = NULL;
  405.     }
  406. }
  407.  
  408. /* CloseAll() - Clean up and possibly print an error report */
  409. void CloseAll (LONG error, ...)
  410. {
  411.     LibDeletePool (FilePool);
  412.  
  413.     if (WorkBench)
  414.     FreeVec (Args->RDA_Source.CS_Buffer);
  415.  
  416.     if (Args)
  417.     {
  418.     FreeArgs (Args);
  419.     FreeDosObject (DOS_RDARGS, Args);
  420.     }
  421.  
  422.     if (error)
  423.     {
  424.     /* Print an error message, either standard or custom... */
  425.  
  426.     if (error > ERROR_SPECIALMAX)
  427.     {
  428.         UBYTE errtxt[80];
  429.  
  430.         Fault (error, "FetchRefs", errtxt, 80);
  431.         PostMessage (errtxt);
  432.     }
  433.     else if (error != ERROR_RUNTWICE)
  434.     {
  435.         va_list args;
  436.  
  437.         va_start (args, error);
  438.         PostMessage (*(STRPTR *)args);
  439.         va_end (args);
  440.     }
  441.     }
  442.     else
  443.     {
  444.     /* Tell that we are stopping by popping a window for a second */
  445.  
  446.     struct TR_Project *stopprj;
  447.     TellWeStopOutline[16].ti_Data = (ULONG) GetString (TEXTE_REMOVE);
  448.     if (stopprj = TR_OpenProject (Application, TellWeStopOutline))
  449.     {
  450.         Delay (TICKS_PER_SECOND);
  451.         TR_CloseProject (stopprj);
  452.     }
  453.     }
  454.  
  455.     if (IntuitionBase)
  456.     CloseLibrary (IntuitionBase);
  457.  
  458.     if (LocaleBase)
  459.     {    CloseCatalog (catalogue);
  460.     CloseLibrary (LocaleBase);
  461.     }
  462.  
  463.     TR_CloseTriton();
  464.     RemoveCx();
  465.     fermeture_port_ARexx();
  466.     _exit((error) && (error != ERROR_RUNTWICE)  ? 5 : 0);
  467. }
  468.  
  469. /* PostMessage() - printf() like requester function. Uses Shell if available */
  470. void PostMessage (STRPTR fmt, ...)
  471. {
  472.     static struct EasyStruct msgreq = {
  473.     sizeof(struct EasyStruct),
  474.     0,
  475.     0,
  476.     NULL,
  477.     0
  478.     };
  479.  
  480.     va_list args;
  481.  
  482.     msgreq.es_Title = GetString (TEXTE_VERSION);
  483.     msgreq.es_GadgetFormat = GetString (TEXTE_OK);
  484.     msgreq.es_TextFormat = fmt;
  485.  
  486.     va_start (args, fmt);
  487.  
  488.     if (WorkBench)
  489.     EasyRequestArgs (NULL, &msgreq, NULL, args);
  490.     else
  491.     {
  492.     VPrintf (fmt, args);
  493.     PutStr ("\n");
  494.     }
  495.  
  496.     va_end (args);
  497. }
  498.  
  499. /* SPrintf() - Low-cost sprintf routine using RawDoFmt()-formatting */
  500. void SPrintf (UBYTE *buf, UBYTE *fmt, ...)
  501. {
  502.     /* The "\x16\xC0\x4E\x75" part is really code that gets executed
  503.      * for each character output:
  504.      *    move.b    d0,(a3)+
  505.      *    rts
  506.      * DATA (move_rts) MUST BE STATIC DO BE USED WITH CACHE PROCESSORS !
  507.      */
  508.     static __aligned char move_rts[4] = { '\x16', '\xC0', '\x4E', '\x75' };
  509.     va_list args;
  510.  
  511.     va_start (args, fmt);
  512.     RawDoFmt (fmt, args, (void *)move_rts, buf);
  513.     va_end (args);
  514. }
  515.  
  516. /* Triton support functions */
  517. struct Library *TritonBase;
  518. struct TR_App *__Triton_Support_App;
  519.  
  520. /****** triton.lib/TR_OpenTriton ******
  521. *   NAME
  522. *    TR_OpenTriton -- Opens Triton ready to use.
  523. *
  524. *   SYNOPSIS
  525. *    success = TR_OpenTriton(version, tag1,...)
  526. *    D0
  527. *
  528. *    BOOL TR_OpenTriton(ULONG, ULONG,...);
  529. *
  530. *   FUNCTION
  531. *    Opens triton.library with the specified minimum
  532. *    version and creates an application.
  533. *    The supplied tags are passed as a taglist to
  534. *    TR_CreateApp().
  535. *
  536. *   RESULT
  537. *    success - Was everything opened successful?
  538. *
  539. *   SEE ALSO
  540. *    TR_CloseTriton(), TR_CreateApp()
  541. ******/
  542.  
  543. BOOL TR_OpenTriton (ULONG version, ULONG taglist,...)
  544. {
  545.     if (!(TritonBase = OpenLibrary (TRITONNAME, version)))
  546.     return FALSE;
  547.     if (!(__Triton_Support_App = TR_CreateApp ((struct TagItem *)&taglist)))
  548.     return FALSE;
  549.  
  550.     return TRUE;
  551. }
  552.  
  553. /* Triton stack arguments stubs */
  554. struct TR_Project * TR_OpenProjectTags (struct TR_App *app, ULONG taglist, ...)
  555. {
  556.     return TR_OpenProject (app, (struct TagItem *)&taglist);
  557. }
  558.  
  559. ULONG TR_EasyRequestTags (struct TR_App *app, STRPTR bodyfmt, STRPTR gadfmt, ULONG taglist, ...)
  560. {
  561.     return TR_EasyRequest (app, bodyfmt, gadfmt, (struct TagItem *)&taglist);
  562. }
  563.  
  564. ULONG TR_AutoRequestTags (struct TR_App *app, struct TR_Project *lockproject, ULONG taglist, ...)
  565. {
  566.     return TR_AutoRequest (app, lockproject, (struct TagItem *)&taglist);
  567. }
  568.